﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Light.Framework.Model;
using Light.Framework.Contract;
using NHibernate.Criterion;
using Light.Framework.Castle;
using Castle.ActiveRecord;
using System.Data;
using Light.Utility;

namespace Light.Framework.Component
{
    /// <summary>
    /// 网点组件
    /// </summary>
    public class OrganizationComponent : BaseComponent<Organization>, IOrganizationComponent
    {

        public Organization GetByPhone(string phone)
        {
            if (String.IsNullOrEmpty(phone))
            {
                return null;
            }
            else
            {
                ICriterion criterion = Expression.Eq("Phone", phone);
                criterion = Expression.And(criterion, GetNotDeletedCriterion());
                return EntityMediator<Organization>.FindFirst(criterion);
            }
        }

        public override Light.Utility.OperateResult Create(Organization obj)
        {
            obj.TimeExpire = DateTime.Now.AddMonths(1);


            OperateResult result = base.Create(obj);

            if (result.IsSucced)
            {
                ClearCache(obj);
            }
            return result;
        }

        public override OperateResult Update(Organization obj)
        {
            OperateResult result = base.Update(obj);

            if (result.IsSucced)
            {
                ClearCache(obj);
            }

            return result;
        }

        public override Light.Utility.OperateResult Delete(int id)
        {
            Light.Utility.OperateResult result = base.Delete(id);

            if (result.IsSucced)
            {
                DeleteLog(id);
            }
            return result;
        }

        public override Light.Utility.OperateResult Delete(Organization obj)
        {
            int id = obj.ID;
            Light.Utility.OperateResult result = base.Delete(obj);

            if (result.IsSucced)
            {
                DeleteLog(id);
                ClearCache(obj);
            }
            return result;
        }

        public IList<Organization> GetSubOrganization(bool includeSelf)
        {
            return GetSubOrganization(ServerApplication.Organization, includeSelf);
        }

        public IList<Organization> GetSubOrganization(Organization org, bool includeSelf)
        {
            if (org == null)
            {
                return null;
            }
            else
            {
                string key = org.ToString() + org.ID;
                IList<Organization> list = ServerApplication.Cache.Get(key) as IList<Organization>;
                if (list == null)
                {
                    list = GetChildren(org);

                    if (list == null)
                        list = new List<Organization>();

                    if (includeSelf && !list.Contains(org))
                    {
                        list.Add(org);
                    }

                    list = list.Distinct().ToList();

                    ServerApplication.Cache.Add(key, list);
                }
                return list;
            }
        }

        /// <summary>
        /// 获取子网点（递归）
        /// </summary>
        /// <param name="org"></param>
        /// <returns></returns>
        private List<Organization> GetChildren(Organization org)
        {
            ICriterion criterion = Expression.Eq("Organization", org);
            criterion = Expression.And(criterion, base.GetNotDeletedCriterion());

            List<Organization> list1 = EntityMediator<Organization>.FindAll(criterion);

            List<Organization> list2 = new List<Organization>();

            foreach (var c in list1)
            {
                if (c.Equals(org))
                {
                    continue;
                }
                List<Organization> temp = GetChildren(c);
                if (temp != null && temp.Count > 0)
                {
                    list2.AddRange(temp);
                }
            }

            list1.AddRange(list2);
            return list1;
        }

        private static void DeleteLog(int orgId)
        {
            try
            {
                ISQLExecuter excuter = SQLManager.CreateExecuter();
                string sql = "DELETE FROM Logs WHERE Organization_ID=@ID";
                IDbDataParameter[] param = excuter.CreateParameter(1);
                param[0].ParameterName = "@ID";
                param[0].Value = orgId;

                excuter.ExecuteNonQuery(sql, param);
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError(ex.Message);
            }

        }

        private static void ClearCache(Organization obj)
        {
            if (obj != null && obj.Organization != null)
            {
                string key = obj.Organization.ToString() + obj.Organization.ID;
                if (ServerApplication.Cache.Get(key) != null)
                {
                    ServerApplication.Cache.Remove(key);
                }
            }
        }

        protected override IList<Organization> Search(ICriterion criterion, int pageIndex, int pageSize, out int totalResult)
        {
            if (!ServerApplication.User.IsSuper)
            {
                criterion = Expression.And(criterion, Expression.Eq("ID", ServerApplication.User.Organization.ID));
            }
            return base.Search(criterion, pageIndex, pageSize, out totalResult);
        }

    }
}
